package com.webank.aigc.service.Alg;

import com.webank.aigc.service.model.BigModelNew;
import com.webank.aigc.service.neo4j.Neo4jService;
import org.neo4j.driver.EagerResult;
import org.neo4j.driver.Record;
import org.neo4j.driver.Value;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Path;
import org.neo4j.driver.types.Relationship;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AIgcServiceImpl implements AlgService{

    final String entityList = "实体：需求,系统,子系统,功能点";
    final String relationList= "关系: 关联(需求关联子系统),拥有(子系统拥有功能点)";
    final String additionText = "不能使用中文符号,不需要其他文本，根据上面的实体和关系及生成一个无查询条件全英文符号的CYPHER查询语句";

    final String outputContent = "1.根据子系统与功能点路径数据分析出当前需求需要涉及到的子系统" +
            "2.根据历史需求分析出与当前需求中可能存在的功能冲突" +
            "3.根据合规风险数据分析出该需求可能的合规风险." +
            "4.根据安全设计数据分析该需求涉及到的安全设计。注意只能根据给出数据要分析，不要杜撰。";
    @Autowired
    private Neo4jService neo4jService;

    @Override
    public Map<String, String> getAnswer(String question) {
        Map<String, String> urls = new HashMap<>();
        try {
            String generateCypher = entityList +"\n" + relationList+"\n"+additionText;
            //1.根据问题生产cypher
            BigModelNew.gpt(generateCypher);
            Thread.sleep(1000);
            //2.等待大模型结果
            while (BigModelNew.threadPoolExecutor.getActiveCount() != 0){};
//            String cypher = convertMoString(BigModelNew.totalAnswer);
//            System.out.println(cypher);
            StringBuilder graphData = new StringBuilder();
            String subSysAndFPData = "子系统与功能点数据："+getSubSystemToFunctionPointPath();
            String requirementData = "历史需求："+getAllHistoryRequirement(urls);
            String lawData = "法律条款数据："+getLawData(urls);
            String SDLData = "SDL安全设计数据："+getSDLData(urls);
            graphData.append(subSysAndFPData+"\n");
            graphData.append(requirementData+"\n");
            graphData.append("当前需求："+question+"\n");
            graphData.append(lawData+"\n");
            graphData.append(SDLData+"\n");

            String finalQuestion = "这是相关数据：\n"+graphData.toString()+"\n"+outputContent;
            System.out.println(finalQuestion);
            BigModelNew.gpt(finalQuestion);
        } catch (Exception e) {
            e.printStackTrace();
        }

       return urls;
    }

    String getAllHistoryRequirement(Map<String, String> urls){
        String cypher = "MATCH (n:`业务需求`) RETURN n.object_key, n.biz_dpms_name,n.url,n.Archives_name LIMIT 100;";
        EagerResult result = neo4jService.query(cypher);
        List<Record> records = result.records();
        StringBuilder answer = new StringBuilder();
        records.stream().forEach(e->{
            answer.append("需求id:");
            answer.append(e.get(0).asString()+" ");
            answer.append("需求描述: ");
            answer.append(e.get(1).asString()+"\n");
            urls.put(e.get(3).asString(),"http://127.0.0.1:8080/"+e.get(2).asString());
        });

        return answer.toString();
    }

    String getLawData(Map<String, String> urls){
        String cypher = "MATCH (n:`法律条款`) RETURN n.law_title, n.law_detail, n.url, n.Archives_name LIMIT 100;";
        EagerResult result = neo4jService.query(cypher);
        List<Record> records = result.records();
        StringBuilder answer = new StringBuilder();
        records.stream().forEach(e->{
            answer.append(e.get(0).asString()+": ");
            answer.append(e.get(1).asString()+"\n");
            urls.put(e.get(3).asString(),"http://127.0.0.1:8080/"+e.get(2).asString());
        });

        return answer.toString();
    }

    String getSDLData(Map<String, String> urls){
        String cypher = "MATCH (n:`安全设计`) RETURN n.sdl_title, n.sdl_detail,n.url,n.Archives_name LIMIT 100;";
        EagerResult result = neo4jService.query(cypher);
        List<Record> records = result.records();
        StringBuilder answer = new StringBuilder();
        records.stream().forEach(e->{
            answer.append(e.get(0).asString()+":");
            answer.append(e.get(1).asString()+"\n");
            urls.put(e.get(3).asString(),"http://127.0.0.1:8080/"+e.get(2).asString());
        });
        return answer.toString();
    }

    String getSubSystemToFunctionPointPath(){
        String cypher = "MATCH p = (:子系统)-[:拥有]->(:功能点) RETURN p;";
        EagerResult result = neo4jService.query(cypher);
        return parseResult(result);
    }

    private static String parseResult(EagerResult result) {
        List<Record> records = result.records();
        StringBuilder answer = new StringBuilder();
        for (Record record : records) {
            Value value = record.get("p");
            if (value.type().name().equals("PATH")) {
                Path path = value.asPath();

                // Print the path
                for (Path.Segment segment : path) {
                    Node startNode = segment.start();
                    Node endNode = segment.end();
                    Relationship relationship = segment.relationship();
                    System.out.println("Start Node:");
                    answer.append(printNode(startNode)+"->");
                    System.out.println("Relationship:");
                    answer.append(printRelationship(relationship)+"->");
                    System.out.println("End Node:");
                    answer.append(printNode(endNode)+"\n");
                }
            } else {
                System.out.println("The value is not a path.");
            }
        }
        return answer.toString();
    }

    private static String printNode(Node node) {
        return "[ID: " + node.id() + ", Labels: " + node.labels()
                + "Properties: " + node.asMap()+" ] ";
    }

    private static String printRelationship(Relationship relationship) {
        return "[ID: " + relationship.id() + ", Type: " + relationship.type()
                + "Properties: " + relationship.asMap()+" ] ";
    }

    public static synchronized String convertMoString(String sMo) {
        String sReturn = sMo;
        if (sReturn == null) {
            return sReturn;
        }
        try {
            sReturn = sReturn.toUpperCase();
            sReturn = sReturn.replace('，', ',');
            sReturn = sReturn.replace('。', '.');
            sReturn = sReturn.replace('；', ';');
            sReturn = sReturn.replace('！', '!');
            sReturn = sReturn.replace('？', '?');
            sReturn = sReturn.replace('：', ':');
            sReturn = sReturn.replace('"', '＂');
            sReturn = sReturn.replace('“', '＂');
            sReturn = sReturn.replace('”', '＂');
            // sReturn = sReturn.replace('-', ' ');
            // sReturn = sReturn.replace('_', ' ');
            sReturn = sReturn.replace('，', ',');
            sReturn = sReturn.replace('0', '0');
            sReturn = sReturn.replace('1', '1');
            sReturn = sReturn.replace('2', '2');
            sReturn = sReturn.replace('3', '3');
            sReturn = sReturn.replace('4', '4');
            sReturn = sReturn.replace('5', '5');
            sReturn = sReturn.replace('6', '6');
            sReturn = sReturn.replace('7', '7');
            sReturn = sReturn.replace('8', '8');
            sReturn = sReturn.replace('9', '9');
            sReturn = sReturn.replace('A', 'A');
            sReturn = sReturn.replace('B', 'B');
            sReturn = sReturn.replace('C', 'C');
            sReturn = sReturn.replace('D', 'D');
            sReturn = sReturn.replace('E', 'E');
            sReturn = sReturn.replace('F', 'F');
            sReturn = sReturn.replace('G', 'G');
            sReturn = sReturn.replace('H', 'H');
            sReturn = sReturn.replace('I', 'I');
            sReturn = sReturn.replace('J', 'J');
            sReturn = sReturn.replace('K', 'K');
            sReturn = sReturn.replace('L', 'L');
            sReturn = sReturn.replace('M', 'M');
            sReturn = sReturn.replace('N', 'N');
            sReturn = sReturn.replace('O', 'O');
            sReturn = sReturn.replace('P', 'P');
            sReturn = sReturn.replace('Q', 'Q');
            sReturn = sReturn.replace('R', 'R');
            sReturn = sReturn.replace('S', 'S');
            sReturn = sReturn.replace('T', 'T');
            sReturn = sReturn.replace('U', 'U');
            sReturn = sReturn.replace('V', 'V');
            sReturn = sReturn.replace('W', 'W');
            sReturn = sReturn.replace('X', 'X');
            sReturn = sReturn.replace('Y', 'Y');
            sReturn = sReturn.replace('Z', 'Z');
            sReturn = strReplace(sReturn, "‘", "'");
        } catch (Exception ex) {
            return sMo;
        }
        return sReturn;
    }

    public static synchronized String strReplace(String sAll, String sOld,String sNew) {
        int iT = 0;
        String sF = null;
        String sH = null;
        /* 如果新串中包括旧串,不让替多只让替少 */
        if (sNew.indexOf(sOld) != -1) {
            return sAll;
        }
        if ((sAll == null) || (sOld == null) || (sNew == null)) {
            return sAll;
        }
        iT = sAll.indexOf(sOld);
        while (iT != -1) {
            sF = sAll.substring(0, iT);
            sH = sAll.substring(iT + sOld.length());
            sAll = sF + sNew + sH;
            iT = sAll.indexOf(sOld);
        }
        return sAll;
    }

}
